using Microsoft.Extensions.Logging;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Services.Notification
{
    /// <summary>
    /// 腾讯云邮件推送服务提供商
    /// 支持腾讯云SES邮件推送服务
    /// </summary>
    public class TencentEmailProvider : IEmailProvider, IDisposable
    {
        public string Name => "腾讯云邮件推送";

        public bool IsConfigured => !string.IsNullOrEmpty(_settings.SecretId) &&
                                   !string.IsNullOrEmpty(_settings.SecretKey) &&
                                   !string.IsNullOrEmpty(_settings.FromAddress);

        private readonly TencentEmailSettings _settings;
        private readonly ILogger _logger;
        private readonly HttpClient _httpClient;
        private const string TENCENT_ENDPOINT = "https://ses.{0}.tencentcloudapi.com/";
        private const string SERVICE = "ses";
        private const string VERSION = "2020-10-02";

        public TencentEmailProvider(TencentEmailSettings settings, ILogger logger)
        {
            _settings = settings ?? throw new ArgumentNullException(nameof(settings));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _httpClient = new HttpClient
            {
                Timeout = TimeSpan.FromSeconds(30)
            };
        }

        /// <summary>
        /// 发送邮件
        /// </summary>
        public async Task<EmailSendResult> SendAsync(EmailMessage message)
        {
            if (!IsConfigured)
            {
                return new EmailSendResult
                {
                    Success = false,
                    ErrorMessage = "腾讯云邮件提供商未正确配置",
                    SentAt = DateTime.UtcNow,
                    Provider = Name
                };
            }

            try
            {
                var requestPayload = BuildSendEmailPayload(message);
                var requestUrl = string.Format(TENCENT_ENDPOINT, _settings.Region);
                
                var startTime = DateTime.UtcNow;
                var response = await SendRequest(requestUrl, "SendEmail", requestPayload);
                var endTime = DateTime.UtcNow;

                if (response.Success)
                {
                    _logger.LogDebug(
                        "腾讯云邮件发送成功 - 收件人: {To}, 主题: {Subject}, 耗时: {Duration}ms",
                        message.To, message.Subject, (endTime - startTime).TotalMilliseconds);

                    return new EmailSendResult
                    {
                        Success = true,
                        MessageId = response.MessageId,
                        SentAt = endTime,
                        Provider = Name
                    };
                }
                else
                {
                    _logger.LogError(
                        "腾讯云邮件发送失败 - 收件人: {To}, 错误: {Error}",
                        message.To, response.ErrorMessage);

                    return new EmailSendResult
                    {
                        Success = false,
                        ErrorMessage = response.ErrorMessage,
                        SentAt = DateTime.UtcNow,
                        Provider = Name
                    };
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "腾讯云邮件发送异常 - 收件人: {To}", message.To);
                
                return new EmailSendResult
                {
                    Success = false,
                    ErrorMessage = ex.Message,
                    SentAt = DateTime.UtcNow,
                    Provider = Name
                };
            }
        }

        /// <summary>
        /// 测试连接
        /// </summary>
        public async Task<bool> TestConnectionAsync()
        {
            if (!IsConfigured)
            {
                _logger.LogWarning("腾讯云邮件提供商未配置，跳过连接测试");
                return false;
            }

            try
            {
                // 使用获取发送统计的API来测试连接
                var payload = new { };
                var requestUrl = string.Format(TENCENT_ENDPOINT, _settings.Region);
                
                var response = await SendRequest(requestUrl, "GetSendEmailStatus", payload);

                if (response.Success || response.ErrorMessage?.Contains("InvalidParameter") == true)
                {
                    // 如果成功或者是参数错误（说明API可访问），都认为连接正常
                    _logger.LogInformation("腾讯云邮件服务连接测试成功");
                    return true;
                }
                else
                {
                    _logger.LogError("腾讯云邮件服务连接测试失败 - 错误: {Error}", response.ErrorMessage);
                    return false;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "腾讯云邮件服务连接测试异常");
                return false;
            }
        }

        /// <summary>
        /// 构建发送邮件的请求载荷
        /// </summary>
        private object BuildSendEmailPayload(EmailMessage message)
        {
            var destination = new List<object>
            {
                new { 
                    ToAddresses = new[] { message.To }
                }
            };

            var template = new
            {
                TemplateData = JsonSerializer.Serialize(new { }),
                TemplateName = "DefaultTemplate"
            };

            var simple = new
            {
                Subject = new
                {
                    Data = message.Subject,
                    Charset = "UTF-8"
                },
                Body = new
                {
                    Text = !string.IsNullOrEmpty(message.TextBody) ? new
                    {
                        Data = message.TextBody,
                        Charset = "UTF-8"
                    } : null,
                    Html = !string.IsNullOrEmpty(message.HtmlBody) ? new
                    {
                        Data = message.HtmlBody,
                        Charset = "UTF-8"
                    } : null
                }
            };

            return new
            {
                Source = !string.IsNullOrEmpty(message.From) ? message.From : _settings.FromAddress,
                Destination = destination,
                Message = simple,
                FromEmailAddress = !string.IsNullOrEmpty(message.From) ? message.From : _settings.FromAddress
            };
        }

        /// <summary>
        /// 发送请求
        /// </summary>
        private async Task<TencentEmailResponse> SendRequest(string endpoint, string action, object payload)
        {
            try
            {
                var jsonPayload = JsonSerializer.Serialize(payload, new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                });

                // 构建请求头
                var headers = BuildHeaders(action, jsonPayload);
                
                var request = new HttpRequestMessage(HttpMethod.Post, endpoint)
                {
                    Content = new StringContent(jsonPayload, Encoding.UTF8, "application/json")
                };

                // 添加头信息
                foreach (var header in headers)
                {
                    if (header.Key == "Content-Type")
                        continue; // Content-Type已经在StringContent中设置
                    
                    request.Headers.TryAddWithoutValidation(header.Key, header.Value);
                }

                var response = await _httpClient.SendAsync(request);
                var responseContent = await response.Content.ReadAsStringAsync();

                if (response.IsSuccessStatusCode)
                {
                    var jsonDoc = JsonDocument.Parse(responseContent);
                    
                    if (jsonDoc.RootElement.TryGetProperty("Response", out var responseElement))
                    {
                        if (responseElement.TryGetProperty("MessageId", out var messageId))
                        {
                            return new TencentEmailResponse
                            {
                                Success = true,
                                MessageId = messageId.GetString()
                            };
                        }
                        else if (responseElement.TryGetProperty("Error", out var error))
                        {
                            var code = error.TryGetProperty("Code", out var codeElement) 
                                ? codeElement.GetString() : "Unknown";
                            var message = error.TryGetProperty("Message", out var messageElement) 
                                ? messageElement.GetString() : "未知错误";
                            
                            return new TencentEmailResponse
                            {
                                Success = false,
                                ErrorMessage = $"腾讯云错误 ({code}): {message}"
                            };
                        }
                        else
                        {
                            return new TencentEmailResponse
                            {
                                Success = true,
                                MessageId = Guid.NewGuid().ToString()
                            };
                        }
                    }
                }

                return new TencentEmailResponse
                {
                    Success = false,
                    ErrorMessage = $"HTTP错误: {response.StatusCode}, 响应: {responseContent}"
                };
            }
            catch (Exception ex)
            {
                return new TencentEmailResponse
                {
                    Success = false,
                    ErrorMessage = ex.Message
                };
            }
        }

        /// <summary>
        /// 构建请求头
        /// </summary>
        private Dictionary<string, string> BuildHeaders(string action, string payload)
        {
            var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
            var date = DateTime.UtcNow.ToString("yyyy-MM-dd");
            
            // 构建规范请求
            var canonicalUri = "/";
            var canonicalQueryString = "";
            var canonicalHeaders = $"content-type:application/json\nhost:ses.{_settings.Region}.tencentcloudapi.com\n";
            var signedHeaders = "content-type;host";
            var hashedPayload = SHA256Hash(payload);
            
            var canonicalRequest = $"POST\n{canonicalUri}\n{canonicalQueryString}\n{canonicalHeaders}\n{signedHeaders}\n{hashedPayload}";
            
            // 构建待签名字符串
            var algorithm = "TC3-HMAC-SHA256";
            var credentialScope = $"{date}/{SERVICE}/tc3_request";
            var hashedCanonicalRequest = SHA256Hash(canonicalRequest);
            var stringToSign = $"{algorithm}\n{timestamp}\n{credentialScope}\n{hashedCanonicalRequest}";
            
            // 计算签名
            var secretDate = HmacSHA256($"TC3{_settings.SecretKey}", date);
            var secretService = HmacSHA256(secretDate, SERVICE);
            var secretSigning = HmacSHA256(secretService, "tc3_request");
            var signature = HmacSHA256(secretSigning, stringToSign, true);
            
            // 构建Authorization头
            var authorization = $"{algorithm} Credential={_settings.SecretId}/{credentialScope}, SignedHeaders={signedHeaders}, Signature={signature}";

            return new Dictionary<string, string>
            {
                ["Authorization"] = authorization,
                ["Content-Type"] = "application/json",
                ["Host"] = $"ses.{_settings.Region}.tencentcloudapi.com",
                ["X-TC-Action"] = action,
                ["X-TC-Timestamp"] = timestamp,
                ["X-TC-Version"] = VERSION,
                ["X-TC-Region"] = _settings.Region
            };
        }

        /// <summary>
        /// SHA256哈希
        /// </summary>
        private static string SHA256Hash(string input)
        {
            using var sha256 = SHA256.Create();
            var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(input));
            return Convert.ToHexString(hash).ToLowerInvariant();
        }

        /// <summary>
        /// HMAC-SHA256
        /// </summary>
        private static byte[] HmacSHA256(byte[] key, string data)
        {
            using var hmac = new HMACSHA256(key);
            return hmac.ComputeHash(Encoding.UTF8.GetBytes(data));
        }

        /// <summary>
        /// HMAC-SHA256 with string key
        /// </summary>
        private static string HmacSHA256(string key, string data, bool hexResult = false)
        {
            using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));
            var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(data));
            return hexResult ? Convert.ToHexString(hash).ToLowerInvariant() : Convert.ToBase64String(hash);
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            _httpClient?.Dispose();
        }
    }

    /// <summary>
    /// 腾讯云邮件响应模型
    /// </summary>
    internal class TencentEmailResponse
    {
        public bool Success { get; set; }
        public string? MessageId { get; set; }
        public string? ErrorMessage { get; set; }
    }
}
